#include <sys_config.h>
#include <types.h>
#include <osal/osal.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <hld/hld_dev.h>
#include <hld/dmx/dmx_dev.h>
#include <hld/dmx/dmx.h>
#include <hld/decv/vdec_driver.h>
#include <hal/hal_gpio.h>

#ifdef SAT2IP_SUPPORT
#include <api/libsat2ip/satip_client_config.h>
#endif

#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_hde.h>
#include <api/libpub29/lib_pub27.h>
#else
#include <api/libpub/lib_hde.h>
#endif

#ifdef SUPPORT_VMX
#include "vmx_ap/vmx_cas.h"
#endif


#include <api/libosd/osd_lib.h>

#include "images.id"
#include "string.id"

#include "osdobjs_def.h"

#include "osd_config.h"
#include "win_com.h"

#include "win_signalstatus.h"

struct vdec_device * get_selected_decoder(void);

#define ICON_ID_SIGNAL_NO				IM_SIGNAL_NO
#define ICON_ID_SIGNAL_LNBSHORT		IM_SIGNAL_NO
#define ICON_ID_SIGNAL_SCRAMBLED		IM_SIGNAL_NO
#define ICON_ID_SIGNAL_PARRENTLOCK	IM_SIGNAL_NO


#define STRING_ID_SIGNAL_NO				RS_MSG_NO_SIGNAL
#define STRING_ID_SIGNAL_LNBSHORT		RS_SYSTEM_KEY_AUDIO_WARNING
#define STRING_ID_SIGNAL_SCRAMBLED		RS_SYSTME_CHANNEL_SCRAMBLED
#define STRING_ID_SIGNAL_PARRENTLOCK		RS_SYSTME_PARENTAL_LOCK


/*******************************************************************************
* WINDOW's objects declaration
*******************************************************************************/
extern CONTAINER g_win_sigstatus;
extern BITMAP sigstatus_bmp1;//,sigstatus_bmp2,sigstatus_bmp3,sigstatus_bmp4;
extern TEXT_FIELD sigstatus_txt;

static BOOL NoSignal_Open = FALSE;
BOOL is_no_signal_status = FALSE;
#ifdef DVR_PVR_SUPPORT
static UINT8 singal_play_chan_nim_busy = 0;
extern BOOL freeze_for_pvr;//black screen result in pvr state trans!
UINT32 last_ca_pmt_cmd_time = 0;
#endif
UINT8 ca_pmt_cmd_cnt = 0;

/*******************************************************************************
*	WINDOW's objects defintion MACRO
*******************************************************************************/
#define WIN_NOSIG_IDX			WSTL_TRANS_IX //WSTL_TRANS_IX
#ifdef OSD_16BIT_SUPPORT
	#define	NOSIG_TXT_IDX		WSTL_TEXT_10_HD //WSTL_MIXBACK_WHITE_IDX_//WSTL_MIXBACK_WHITE_IDX
#else
	#define	NOSIG_TXT_IDX		WSTL_MIXBACK_IDX_02_8BIT //WSTL_MIXBACK_WHITE_IDX_//WSTL_MIXBACK_WHITE_IDX
#endif
#define	NOSIG_BMP_IDX		    WSTL_MIXBACK_IDX_06_8BIT //WSTL_MIXBACK_BLACK_IDX

#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,resID,str)	\
	DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
    	0,0,0,0,0, l,t,w,h, NOSIG_TXT_IDX, NOSIG_TXT_IDX, NOSIG_TXT_IDX,NOSIG_TXT_IDX,   \
    	NULL, NULL,  \
    	C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,resID,str)

#define LDEF_BMP(root,varBmp,nxtObj,l,t,w,h,icon)		\
	DEF_BITMAP(varBmp,root,nxtObj,C_ATTR_ACTIVE,0, \
    	0,0,0,0,0, l,t,w,h, NOSIG_BMP_IDX,NOSIG_BMP_IDX,NOSIG_BMP_IDX,NOSIG_BMP_IDX,   \
    	NULL,NULL,  \
    	C_ALIGN_CENTER | C_ALIGN_VCENTER, 0,0,icon)

#define LDEF_WIN(varWnd,nxtObj,l,t,w,h,focusID)		\
	DEF_CONTAINER(varWnd,NULL,NULL,C_ATTR_ACTIVE,0, \
    	0,0,0,0,0, l,t,w,h, WSTL_TRANS_IX,WSTL_TRANS_IX,WSTL_TRANS_IX,WSTL_TRANS_IX,   \
    	NULL,NULL,  \
    	nxtObj, focusID,0)

#ifndef SD_UI
#define W_L	 404//362    //498 //204//192
#define W_T	 208    //208 //90
#define W_W	200
#define W_H	 140

#define POP_OFFSET_L	60

#define BMP1_L	W_L//548 //246
#define BMP1_T	W_T//208 //90
#define BMP1_W	W_W//98  //94
#define BMP1_H	98  //94

#define TXT_L	W_L //192
#define TXT_T	(W_T + 100)  //308 //188
#define TXT_W	W_W
#define TXT_H	40

#else
#define W_L	 204//362    //498 //204//192
#define W_T	 90    //208 //90
#define W_W	200
#define W_H	 128

#define POP_OFFSET_L	60

#define BMP1_L	257//548 //246
#define BMP1_T	90//208 //90
#define BMP1_W	94//98  //94
#define BMP1_H	94  //94

#define TXT_L	W_L //192
#define TXT_T	188  //308 //188
#define TXT_W	200
#define TXT_H	26
#endif
/*******************************************************************************
*	WINDOW's objects defintion
*******************************************************************************/
LDEF_BMP(&g_win_sigstatus, sigstatus_bmp1, &sigstatus_txt,  BMP1_L, BMP1_T, BMP1_W, BMP1_H, ICON_ID_SIGNAL_NO)
LDEF_TXT(&g_win_sigstatus,sigstatus_txt,NULL, TXT_L, TXT_T,TXT_W, TXT_H, STRING_ID_SIGNAL_NO, NULL)

LDEF_WIN(g_win_sigstatus, &sigstatus_bmp1, W_L, W_T, W_W, W_H, 1)

/*******************************************************************************
*	Local vriable & function declare
*******************************************************************************/



/*******************************************************************************
*  WINDOW's  keymap, proc and callback
*******************************************************************************/



/*******************************************************************************
*	Menu Item ---  callback, keymap and proc
*******************************************************************************/



/*********************************************************************************
*	Window handle's open,proc and handle
**********************************************************************************/


signal_lock_status      lv_lock_status      = SIGNAL_STATUS_LOCK;
signal_scramble_status  lv_scramble_status  = SIGNAL_STATUS_UNSCRAMBLED;
signal_lnbshort_status  lv_lnbshort_status  = SIGNAL_STATUS_LNBNORMAL;
signal_parentlock_status lv_parrentlock_status = SIGNAL_STATUS_PARENT_UNLOCK;
#ifdef PARENTAL_SUPPORT
signal_ratinglock_status lv_ratinglock_status = SIGNAL_STATUS_RATING_UNLOCK;
signal_pvr_ratinglock_status lv_pvr_ratinglock_status = SIGNAL_STATUS_PVR_RATING_UNLOCK;
#endif
UINT8                   lv_scramble_fake;

UINT32 g_signal_scram_flag;
UINT32 g_signal_unlock_flag;

#if(SYS_LNB_SHORT_DET == SYS_FUNC_ON)
UINT8 lnb_power_short = SIGNAL_STATUS_LNBNORMAL;
UINT8 short_detect_flag = 0;
#endif
#ifdef SYS_12V_SHORT_DET
#if(SYS_12V_SHORT_DET== SYS_FUNC_ON)
UINT8 v12_power_short = SIGNAL_STATUS_LNBNORMAL;
#endif
#endif

#define WIN_SIGNAL_SHOW_MASK    0xffff  // 0xffff -- 16 times
#ifdef SUPPORT_VMX
#define WIN_SCRAMBLE_SHOW_MASK    0x0003  // 0x0003 -- 2 times
#endif

static BOOL win_signal_status_show_unlocked(void)
{
	return ((g_signal_unlock_flag & WIN_SIGNAL_SHOW_MASK) == WIN_SIGNAL_SHOW_MASK);
}

static BOOL win_signal_status_show_scrambled(void)
{
	#ifdef SUPPORT_VMX
	return ((g_signal_scram_flag & WIN_SCRAMBLE_SHOW_MASK) == WIN_SCRAMBLE_SHOW_MASK);
	#else
	return ((g_signal_scram_flag & WIN_SIGNAL_SHOW_MASK) == WIN_SIGNAL_SHOW_MASK);
	#endif
}

static void SetSingnalStr(void)
{
    TEXT_FIELD*  txt;
    BITMAP*    bmp;

    UINT16 strID;
    UINT16 imageID;

	txt = &sigstatus_txt;
	bmp = &sigstatus_bmp1;

	if(lv_parrentlock_status == SIGNAL_STATUS_PARENT_LOCK)
	{
		imageID = ICON_ID_SIGNAL_PARRENTLOCK;
		strID = STRING_ID_SIGNAL_PARRENTLOCK;
	}
#ifdef PARENTAL_SUPPORT
	else if (lv_ratinglock_status == SIGNAL_STATUS_RATING_LOCK)
	{
		imageID = ICON_ID_SIGNAL_PARRENTLOCK;
		strID = STRING_ID_SIGNAL_PARRENTLOCK;
	}
#endif
	else if (win_signal_status_show_unlocked())
	{
	    imageID = ICON_ID_SIGNAL_NO;
	    strID = STRING_ID_SIGNAL_NO;
	}
	else if (win_signal_status_show_scrambled())
	{
	    imageID = ICON_ID_SIGNAL_SCRAMBLED;
	    strID = STRING_ID_SIGNAL_SCRAMBLED;
	}
	else if(lv_lnbshort_status == SIGNAL_STATUS_LNBSHORT
#ifdef SYS_12V_SHORT_DET
#if(SYS_12V_SHORT_DET== SYS_FUNC_ON)
		|| v12_power_short == SIGNAL_STATUS_LNBSHORT
#endif
#endif
			)
	{
	    imageID = ICON_ID_SIGNAL_LNBSHORT;
	    strID = STRING_ID_SIGNAL_LNBSHORT;
	}
	else 
	{
		imageID = 0;
		strID = 0;
	}

	OSD_SetTextFieldContent(txt, STRING_ID, strID);
	OSD_SetBitmapContent(bmp, imageID);
}

static void SetSignalLockStatus(signal_lock_status lock_flag)
{
    lv_lock_status = lock_flag;
    g_signal_unlock_flag <<= 1;
    if (lock_flag == SIGNAL_STATUS_UNLOCK)
        g_signal_unlock_flag++;
    SetSingnalStr();
}

static void SetSignalScrambleStatus(signal_lnbshort_status lnbshort_flag)
{
    lv_scramble_status = lnbshort_flag;
    g_signal_scram_flag <<= 1;
    if (lnbshort_flag == SIGNAL_STATUS_SCRAMBLED)
        g_signal_scram_flag++;
    SetSingnalStr();    
}

static void SetSignalLNBShortStatus(signal_lock_status lnbshort_flag)
{
    lv_lnbshort_status = lnbshort_flag ;
    SetSingnalStr();
}

void SetChannelParrentLock(signal_parentlock_status parrentlock_flag)
{
    lv_parrentlock_status = parrentlock_flag;
    SetSingnalStr();
}

BOOL GetChannelParrentLock(void)
{
    return (lv_parrentlock_status == SIGNAL_STATUS_PARENT_LOCK) ? TRUE : FALSE;
}

#ifdef PARENTAL_SUPPORT
void SetRatingLock(signal_ratinglock_status ratinglock_flag)
{
    lv_ratinglock_status = ratinglock_flag;
    SetSingnalStr();
}
BOOL GetRatingLock(void)
{
    return (lv_ratinglock_status == SIGNAL_STATUS_RATING_LOCK) ? TRUE : FALSE;
}
void SetPVRRatingLock(signal_pvr_ratinglock_status ratinglock_flag)
{
    lv_pvr_ratinglock_status = ratinglock_flag;
    SetSingnalStr();
}
BOOL GetPVRRatingLock(void)
{
    return (lv_pvr_ratinglock_status == SIGNAL_STATUS_PVR_RATING_LOCK) ? TRUE : FALSE;
}
#endif 
BOOL GetChannelScramble(void)
{
	return (lv_scramble_status == SIGNAL_STATUS_SCRAMBLED) ? TRUE : FALSE;
}

BOOL GetSignalStatus(  signal_lock_status* lock_flag,
                        signal_scramble_status* scramble_flag,
                        signal_lnbshort_status* lnbshort_flag,
                        signal_parentlock_status* parrentlock_flag
                        #ifdef PARENTAL_SUPPORT
                        ,signal_ratinglock_status* ratinglock_flag
                        #endif    
                        )
{
    UINT8 lock;
    struct dmx_device * dmx_dev;
    signal_lnbshort_status lnbshort;
    SYSTEM_DATA* sys_data;
    sys_data = sys_data_get();    
    UINT8 scrabled,scrable_typ;
    P_NODE p_node;
    UINT16 cur_channel;
    struct VDec_StatusInfo curStatus;
    static UINT16 prechan;
    static UINT32 descDetTime = 0;
	struct nim_device* nim_dev;
#ifdef NEW_DEMO_FRAME
    static UINT32 unlock_times;
	INT32 ts_route_id;
	struct ts_route_info ts_route;
    struct nim_config nim_config;
#endif

	if(cur_tuner_idx == 0)
		nim_dev = g_nim_dev;
	else
		nim_dev = g_nim_dev2;	
    
#ifdef NEW_DEMO_FRAME
	MEMSET(&ts_route, 0, sizeof(struct ts_route_info));
	if(ts_route_get_by_type(TS_ROUTE_MAIN_PLAY, &ts_route_id, &ts_route) != RET_FAILURE)
	{
		nim_dev = (struct nim_device *)dev_get_by_id(HLD_DEV_TYPE_NIM, ts_route.nim_id);
	}
	else
	{
		nim_dev = (cur_tuner_idx == 0) ? g_nim_dev : g_nim_dev2;
	}
#endif

    
    lnbshort = SIGNAL_STATUS_LNBNORMAL;

#if(SYS_LNB_SHORT_DET == SYS_FUNC_ON)

    /*  
    if(sys_data->bLNB_power == LNB_POWER_ON)
    {
        if(LNB_state() == 1)//short
        {
            lnbshort = SIGNAL_STATUS_LNBSHORT;
        }
    }
    */
    lnbshort = lnb_power_short;    
#elif(SYS_12V_SHORT_DET == SYS_FUNC_ON)
	lnbshort = v12_power_short;
#endif

    if(lnbshort_flag != NULL)
        *lnbshort_flag = lnbshort;    
    SetSignalLNBShortStatus(lnbshort);

//    if(*lnbshort_flag  == SIGNAL_STATUS_LNBSHORT)
//        return TRUE;    
    
#ifdef NEW_DEMO_FRAME
	dmx_dev = (struct dmx_device *)dev_get_by_id(HLD_DEV_TYPE_DMX, ts_route.dmx_id);
#else
	dmx_dev = g_dmx_dev;
#endif

#ifdef DVR_PVR_SUPPORT
	if(singal_play_chan_nim_busy)
		lock = SIGNAL_STATUS_UNLOCK;
	else
#endif
    nim_get_lock(nim_dev,&lock);
#if 0//def NEW_DEMO_FRAME  //reset diseqc, but it may hold this process, if attached to UI flow maybe cause bug!
	if(!lock)
		unlock_times++;
	else 
		unlock_times = 0;
	if((unlock_times > 10)&& sys_data->bLNB_power)
	{
		dev_get_nim_config(nim_dev, FRONTEND_TYPE, &nim_config);
		frontend_set_antenna(nim_dev, &nim_config.antenna, &nim_config.xpond, 1); 
		if(frontend_lnb_22k_ctl(&nim_config.antenna) || (nim_dev == g_nim_dev2))
			frontend_set_nim(nim_dev, &nim_config.antenna,&nim_config.xpond,1);
		
		nim_get_lock(nim_dev,&lock);
		unlock_times = 0;  
	}
#endif

    if (parrentlock_flag == NULL)
        lv_lock_status = lock? SIGNAL_STATUS_LOCK : SIGNAL_STATUS_UNLOCK;
    else
	    SetSignalLockStatus( lock? SIGNAL_STATUS_LOCK : SIGNAL_STATUS_UNLOCK);

#if(defined(SUPPORT_DVTCA))
		static UINT32 unlock_time=0;
		if(!lock)
			unlock_time++;
		else
			unlock_time=0;
		if(unlock_time>=3)
			ap_set_signal_status(TRUE);
		else
			ap_set_signal_status(FALSE);
#endif

	cur_channel = sys_data_get_cur_group_cur_mode_channel();
	get_prog_at(cur_channel,&p_node);

#if 0
	scrabled = 0;
	if(dmx_io_control(dmx_dev,IS_AV_SCRAMBLED,(UINT32)(&scrable_typ)) == RET_SUCCESS )
	{
		if(scrable_typ & (VDE_TS_SCRBL|VDE_PES_SCRBL))
			scrabled = 1;
		else
		{
			scrabled = 0;			
		}
	}
#else
    scrabled = key_get_dmx0_scramble(NULL);
#endif
#if defined(SUPPORT_VMX_STD) || defined(SUPPORT_VMX)
	BOOL fvmxscrambled=FALSE;
	static BOOL fprescrambled=FALSE;

	#if defined(SUPPORT_VMX_STD) && !defined(VMX_NEW_CC)
	if (Get_CA_Descrambling_State() && (p_node.ca_mode) 
	#else
	if (Get_CA_Descrambling_State(vmx_get_viewing_service_idx()) && (p_node.ca_mode) 
	#endif
		&& (!scrabled) && lock && (screen_back_state == SCREEN_BACK_VIDEO) 
		&& (VIEW_MODE_FULL == hde_get_mode()) 	)
	{
	    vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
		UINT32 freeze_flag = curStatus.display_idx;
		if((curStatus.uFirstPicShowed)  && (curStatus.uCurStatus == VDEC_DECODING)) //for scramble prog and freeze screen (show black screen and scramble osd) 
		{
			osal_task_sleep(100);
			vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
			if(freeze_flag == curStatus.display_idx)
			{
				osal_task_sleep(100);
				vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
				if(freeze_flag == curStatus.display_idx) // freeze screen state!
				{
					fvmxscrambled = 1;	
				}
                else
                {
                    ca_pmt_cmd_cnt = 0;
                }
			}
            else
            {
                ca_pmt_cmd_cnt = 0;
            }
		}
		else if(!curStatus.uFirstPicShowed) //for scramble prog and black screen
		{
			fvmxscrambled = 1;
            ca_pmt_cmd_cnt = 0;
		}
	}

	if(fvmxscrambled)
	{
		if(fprescrambled == FALSE)
		{
			if(SYS_STATE_USB_PVR != system_state)
			{
				//libc_printf("%s():call api_disp_blackscreen @ line %d\n", __func__, __LINE__);
				api_disp_blackscreen(TRUE, FALSE);
				api_disp_blackscreen(FALSE, FALSE);
			}
			fprescrambled = TRUE;
		}
	}
	else
	{
		fprescrambled = FALSE;
	}	
	scrabled |=fvmxscrambled;	
#endif
#ifdef CI_SUPPORT2
	if ((parrentlock_flag == NULL) && (p_node.ca_mode) && (!scrabled) && lock && (screen_back_state == SCREEN_BACK_VIDEO) && (VIEW_MODE_FULL == hde_get_mode()) 
#ifdef DVR_PVR_SUPPORT
		&& !freeze_for_pvr //black screen result in pvr state trans!
		&& api_pvr_is_live_playing()
#endif
		)
	{
	    vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
		UINT32 freeze_flag = curStatus.display_idx;
		if((curStatus.uFirstPicShowed)  && (curStatus.uCurStatus == VDEC_DECODING)) //for scramble prog and freeze screen (show black screen and scramble osd) 
		{
			osal_task_sleep(100);
			//vdec_io_control(g_decv_dev, VDEC_IO_GET_STATUS, (UINT32)&curStatus);
			vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
			if(freeze_flag == curStatus.display_idx)
			{
				osal_task_sleep(100);
				//vdec_io_control(g_decv_dev, VDEC_IO_GET_STATUS, (UINT32)&curStatus);
				vdec_io_control(get_selected_decoder(), VDEC_IO_GET_STATUS, (UINT32)&curStatus);
				if(freeze_flag == curStatus.display_idx) // freeze screen state!
				{
					scrabled = 1;	
#ifdef DVR_PVR_SUPPORT //add to simulate monitor's function for video hold state because monitor is off under DVR project!
					if((!last_ca_pmt_cmd_time) || (last_ca_pmt_cmd_time && (osal_get_tick() > last_ca_pmt_cmd_time + 6000)))
					{
						if(ca_pmt_cmd_cnt >= 2)
						{
							UIChChgPlayProg(0,CC_CMD_RESET_CRNT_CH);
							ca_pmt_cmd_cnt = 0;
						}
						else
						{
							//cc_send_ca_pmt();
							cc_send_ca_pmt(p_node.prog_id);
							ca_pmt_cmd_cnt++;
						}
						last_ca_pmt_cmd_time = osal_get_tick();
					}
#endif
				}
                else
                {
                    ca_pmt_cmd_cnt = 0;
                }
			}
            else
            {
                ca_pmt_cmd_cnt = 0;
            }
		}
		else if(!curStatus.uFirstPicShowed) //for scramble prog and black screen
		{
			scrabled = 1;
            ca_pmt_cmd_cnt = 0;
		}
	}
#endif

    if (parrentlock_flag)
    {
        if (scrabled)
        {
            if (lv_scramble_fake)
                scrabled = 0;
        }
    	SetSignalScrambleStatus(scrabled? SIGNAL_STATUS_SCRAMBLED : SIGNAL_STATUS_UNSCRAMBLED);
    }
    else
    {
        if (lock_flag == NULL && lnbshort_flag == NULL)
        {
            // special case, just return the CA flag
            scrabled = p_node.ca_mode;
        }
        lv_scramble_status = scrabled? SIGNAL_STATUS_SCRAMBLED : SIGNAL_STATUS_UNSCRAMBLED;
    }

    /*Never in In multi-view mode*/
    if(lock && !scrabled && hde_get_mode()!=VIEW_MODE_MULTI)
    {
        if(p_node.ca_mode && sys_data_get_cur_chan_mode() == TV_CHAN)
        {
            if(!curStatus.uFirstPicShowed && curStatus.uCurStatus!=VDEC_PAUSED)
            {
                descDetTime ++;
                if(descDetTime == 1)
                    prechan = cur_channel;
                if(descDetTime >=3 && prechan == cur_channel)
                    scrabled = 1;
                else
                    descDetTime = 0;                    
            }
            else
                descDetTime = 0;
        }
    }   

    if(lock_flag != NULL)
        *lock_flag = lv_lock_status;
    if(scramble_flag != NULL)
        *scramble_flag = lv_scramble_status;
    if(parrentlock_flag != NULL)
        *parrentlock_flag = lv_parrentlock_status;
#ifdef PARENTAL_SUPPORT
    if(ratinglock_flag != NULL)
        *ratinglock_flag = lv_ratinglock_status;
#endif
	
    if(lv_lock_status == SIGNAL_STATUS_LOCK 
        && lv_scramble_status == SIGNAL_STATUS_UNSCRAMBLED
        && lv_lnbshort_status == SIGNAL_STATUS_LNBNORMAL
        && lv_parrentlock_status == SIGNAL_STATUS_PARENT_UNLOCK
#ifdef PARENTAL_SUPPORT
	&& lv_ratinglock_status == SIGNAL_STATUS_RATING_UNLOCK
#endif

	)
    {
        return FALSE;
    }
    else
    {
    #if 0 //def SAT2IP_CLIENT_SUPPORT
        // no need to show no singnal when play SAT2IP program.
        if (api_cur_prog_is_sat2ip()    \
            && lv_lock_status == SIGNAL_STATUS_UNLOCK )
            return FALSE;
    #endif

        return TRUE;        
    }
}

BOOL signal_stataus_showed = FALSE;

BOOL GetSignalStatausShow(void)
{
    return signal_stataus_showed;
}

#ifdef SUPPORT_CAS9
extern UINT8 ui_show_flg;
#endif
void ShowSignalStatusOSDOnOff(UINT8 flag)
{
    OBJECT_HEAD* obj;
    POBJECT_HEAD topmenu =NULL;
    BOOL  bifClear = 1;
    struct OSDRect relative_rect;
 #if(defined(SUPPORT_DVTCA))
		return;
#endif
#ifdef _INVW_JUICE   
    if (inview_is_running()) {
      return;
    }
#endif
    obj = (OBJECT_HEAD*)&g_win_sigstatus;
    
#if(defined(SUPPORT_CAS_A))
	if(api_abel_osd_get_cas_msg_num()&&flag)
	{

		if(signal_stataus_showed==TRUE)
		{
			OSD_ClearObject(obj, 0);
			signal_stataus_showed=FALSE;
		}		
		return;
	}
#endif   
	
#ifdef SUPPORT_CAS9
    if((1 == flag) && (1 == ui_show_flg))
    {
        /* if host message is displaying, we should not open "No Signal" window, host message priority is higher than it */
        return;
    }
#endif	
  
    topmenu =(POBJECT_HEAD)menu_stack_get_top();//@Alan modify  
    if(topmenu && topmenu != obj)
    {
        relative_rect.uWidth = 0;
        relative_rect.uHeight = 0;
        OSD_GetRectsCross(&(topmenu->frame),&(obj->frame),&relative_rect);
        if(relative_rect.uHeight != 0 && relative_rect.uWidth != 0)
        {
            bifClear = 0;
        }        
    }

	#ifndef _BUILD_OTA_E_
    //rec_poplist_display  has been linked to top window in some case.
    //So there are more than one windows are showing on the screen at the same time. 
   if(bifClear &&  is_rec_poplist_displaying()) 
   {
   	extern CONTAINER 	g_win_pvr_recpoplist;
	 topmenu = (POBJECT_HEAD)&g_win_pvr_recpoplist;
        relative_rect.uWidth = 0;
        relative_rect.uHeight = 0;
        OSD_GetRectsCross(&(topmenu->frame),&(obj->frame),&relative_rect);
        if(relative_rect.uHeight != 0 && relative_rect.uWidth != 0)
        {
            bifClear = 0;
        }       
   }
   #endif
	
    if(flag)
        OSD_DrawObject(obj, C_UPDATE_ALL);
    else
        //OSD_ClearObject(obj, 0);
    {
        bifClear ? OSD_ClearObject(obj, 0):NULL;//@Alan modify
    }
    signal_stataus_showed = flag ? TRUE : FALSE;
}

void conax_remove_mutex();
void ShowSignalStatusOnOff(void)
{
    UINT8 flag;
    signal_lock_status lock_flag;
    signal_scramble_status scramble_flag;
    signal_lnbshort_status lnbshort_flag;    
    signal_parentlock_status parrentlock_flag;

#ifdef CI_PLUS_SUPPORT
    if(IsCIPlus_Menu_Exist())
        return;
#endif

#ifdef PARENTAL_SUPPORT
    signal_ratinglock_status ratinglock_flag;
    if(GetSignalStatus(&lock_flag, &scramble_flag,&lnbshort_flag,&parrentlock_flag,&ratinglock_flag) == FALSE) 
#else
    if(GetSignalStatus(&lock_flag,&scramble_flag,&lnbshort_flag,&parrentlock_flag) == FALSE)
#endif
    {
        flag = 0;
	 is_no_signal_status= FALSE;
    }
    else
    {
        flag = 1;
	is_no_signal_status= TRUE;
    }
        
#ifdef SUPPORT_CAS9
	struct smc_device *smc_dev = (struct smc_device *)dev_get_by_id(HLD_DEV_TYPE_SMC, 0);
	if((smc_card_exist(smc_dev) == SUCCESS) && flag 
		&& (sigstatus_txt.wStringID ==STRING_ID_SIGNAL_SCRAMBLED))
	{
		return;
	}
#endif
    ShowSignalStatusOSDOnOff(flag);
}



extern char    led_display_data[10];
extern UINT8   led_data_len;
extern UINT8   led_display_flag;

#if(SYS_LNB_SHORT_DET == SYS_FUNC_ON)    
UINT8   lnb_power_detect_start = 0;
void lnb_power_short_detect(void)
{

    SYSTEM_DATA* sys_data;
    static UINT32 count = 0;
    UINT32 lnb_short;
    static UINT8 lnb_short_cut =0 ;
    static UINT8 det_start = 0;
#define LNB_POWER_RESET_WAIT_TIME 100

    if(!lnb_power_detect_start && !det_start) 
        return;
    det_start = 1;

    sys_data = sys_data_get();    

    if(sys_data->bLNB_power == LNB_POWER_ON)
    {
        if(!lnb_short_cut)  /* If not cut it forcedly*/
        {
            lnb_short = board_lnb_state(0);  //api_LNB_state();
            if(lnb_short == 0)
               lnb_short = board_lnb_state(1);  
            
            if(lnb_short == 1)  /* LNB short detected*/
            {
                /* Cut LNB Power*/
               // api_LNB_power(0);
                board_lnb_power(0, 0);
                board_lnb_power(1, 0);

                /* Set corresponding flags*/
                lnb_power_short = SIGNAL_STATUS_LNBSHORT;
                lnb_short_cut = 1;            
                count = 0;

                /* Set LED display */
                led_display_flag = 1;
				key_pan_display("LnbP",4);
                led_display_flag = 2;
            }
            else
            {
                if(lnb_power_short == SIGNAL_STATUS_LNBSHORT 
                    || led_display_flag != 0)
                {
                    /* Restore LED display*/
                    led_display_flag = 1;
                    key_pan_display(led_display_data,led_data_len);
                    led_display_flag = 0;
                    lnb_power_short = SIGNAL_STATUS_LNBNORMAL;
                }
                
            }
        }
        else    /* If have already cut it forcedly*/
        {
            count++;
            if(count >= LNB_POWER_RESET_WAIT_TIME)
            {
                /* Restore LNB Power*/
                //api_LNB_power(sys_data->bLNB_power); 
                board_lnb_power(0, 1);
                lnb_short_cut = 0;
                count = 0;
            }
        }
    }
    else    /* User set LNB Power off */
    {
        if(lnb_power_short == SIGNAL_STATUS_LNBSHORT 
            || led_display_flag != 0)
        {
            /* Restore LED display*/
            led_display_flag = 1;
			key_pan_display(led_display_data,led_data_len);
            led_display_flag = 0;
            lnb_power_short = SIGNAL_STATUS_LNBNORMAL;
        }
        lnb_short_cut = 0; 
        count = 0;    
    }
}
#endif	

#ifdef SYS_12V_SWITCH
#if(SYS_12V_SWITCH == SYS_FUNC_ON)
	volatile int v12_detect = 0;
#endif
#endif

void v12_set_callback(UINT32 v12)
{
#ifdef SYS_12V_SWITCH
#if(SYS_12V_SWITCH == SYS_FUNC_ON)
	v12_detect = v12;
#endif
#endif
}

void v12_power_short_detect(UINT32 nouse)
{
#if(defined(SYS_12V_SWITCH) && defined(SYS_12V_SHORT_DET))

#if(SYS_12V_SWITCH==SYS_FUNC_ON && SYS_12V_SHORT_DET == SYS_FUNC_ON)
	INT32 v12,v12_short;
	static INT32 oldv12 = -1;
	static UINT8 v12_short_cut =0 ;
    static UINT32 count = 0;
#define V12_POWER_RESET_WAIT_TIME 100

	if(!v12_short_cut)
	{
		if(!v12_detect)
			return;		

		HAL_GPIO_BIT_DIR_SET(SYS_12V_SHORT_DET_GPIO, HAL_GPIO_I_DIR);
		v12_short = HAL_GPIO_BIT_GET(SYS_12V_SHORT_DET_GPIO);

		v12_short = v12_short? 0 : 1;	/* Polarity reverse */

        if(v12_short == 1)  /* V12 short detected*/
        {
            /* Cut V12 Power*/            
			HAL_GPIO_BIT_DIR_SET(SYS_12V_GPIO, HAL_GPIO_O_DIR);
			HAL_GPIO_BIT_SET(SYS_12V_GPIO,0);

            /* Set corresponding flags*/
            v12_power_short = SIGNAL_STATUS_LNBSHORT;
            v12_short_cut = 1;            
            count = 0;

            /* Set LED display */
            led_display_flag = 1;
			key_pan_display("12SP",4);
            led_display_flag = 2;
        }
        else
        {
RESET_V12_STATUS:
            if(v12_power_short == SIGNAL_STATUS_LNBSHORT 
                || led_display_flag != 0)
            {
                /* Restore LED display*/
                led_display_flag = 1;
                key_pan_display(led_display_data,led_data_len);
                led_display_flag = 0;
                v12_power_short = SIGNAL_STATUS_LNBNORMAL;
            }
            
        }		
	}
	else
	{
		if(!v12_detect)/* User have re-set V12 */
		{
			v12_short_cut = 0;
			goto RESET_V12_STATUS;
		}
		count++;
		if(count >= V12_POWER_RESET_WAIT_TIME)
		{
			/* Restore LNB Power*/
			HAL_GPIO_BIT_DIR_SET(SYS_12V_GPIO, HAL_GPIO_O_DIR);
			HAL_GPIO_BIT_SET(SYS_12V_GPIO,v12_detect);
			v12_short_cut = 0;
			count = 0;
		}
	}
#endif
#endif
}

void SetLNBShortDetect(UINT32 flag)
{

#if(SYS_LNB_SHORT_DET == SYS_FUNC_ON)

#if 1    //use task instead of interrupt
    
    short_detect_flag = flag;

#else
    static UINT8 set = 0;

    if(!set && flag)
    {
        osal_interrupt_register_lsr(7, lnb_power_short_detect, 0);
        set = 1;
    }
    else if(set && !flag)   
    {
        osal_interrupt_unregister_lsr(7, lnb_power_short_detect);
        lnb_power_short = SIGNAL_STATUS_LNBNORMAL;
        led_display_flag = 0;
        set = 0;
    }
#endif    
#endif	
}

void SetLNBShortDetectStart(UINT32 flag)
{
#if(SYS_LNB_SHORT_DET == SYS_FUNC_ON)    
	lnb_power_detect_start = (UINT8)flag;
#endif
}

void GetSignalStatusRect(OSD_RECT* rect)
{
	POBJECT_HEAD obj;

	obj = (POBJECT_HEAD)&g_win_sigstatus;
	*rect = obj->frame;
}

void SetChannelNimBusy(UINT32 flag)
{
#ifdef DVR_PVR_SUPPORT
	singal_play_chan_nim_busy = (UINT8)flag;
#endif
}


void Set12VShortDetect(UINT32 flag)
{
#if(defined(SYS_12V_SWITCH) && defined(SYS_12V_SHORT_DET))

#if(SYS_12V_SWITCH==SYS_FUNC_ON && SYS_12V_SHORT_DET == SYS_FUNC_ON)

	UIChChgSet12VSetCB(v12_set_callback);

	static UINT8 set = 0;
    if(!set && flag)
    {
        osal_interrupt_register_lsr(7, v12_power_short_detect, 0);
        set = 1;
    }
    else if(set && !flag)   
    {
        osal_interrupt_unregister_lsr(7, v12_power_short_detect);
        v12_power_short = SIGNAL_STATUS_LNBNORMAL;
        led_display_flag = 0;
        set = 0;
    }
#endif	
#endif
}

void shift_signal_osd()
{
	CONTAINER * signal_con = &g_win_sigstatus;
	TEXT_FIELD * signal_txt = &sigstatus_txt;
	BITMAP *signal_bmp = &sigstatus_bmp1;

	signal_con->head.frame.uLeft = (signal_con->head.frame.uLeft) + POP_OFFSET_L;
	signal_txt->head.frame.uLeft = (signal_txt->head.frame.uLeft) + POP_OFFSET_L;
	signal_bmp->head.frame.uLeft = (signal_bmp->head.frame.uLeft) + POP_OFFSET_L;
}
void restore_signal_osd()
{
	CONTAINER * signal_con = &g_win_sigstatus;
	TEXT_FIELD * signal_txt = &sigstatus_txt;
	BITMAP *signal_bmp = &sigstatus_bmp1;

	signal_con->head.frame.uLeft = (signal_con->head.frame.uLeft) - POP_OFFSET_L;
	signal_txt->head.frame.uLeft = (signal_txt->head.frame.uLeft) - POP_OFFSET_L;
	signal_bmp->head.frame.uLeft = (signal_bmp->head.frame.uLeft) - POP_OFFSET_L;
}

void set_signal_scramble_fake(UINT8 bFake)
{
    lv_scramble_fake = bFake;
}

UINT8 get_signal_scramble_fake()
{
    return 0;
    //return lv_scramble_fake;
}

extern P_NODE playing_pnode;
BOOL api_is_stream_scrambled(void)
{
    UINT8 scrabled = 0;	

	if(playing_pnode.prog_id != 0)
	{
#ifdef _INVW_JUICE   
#else
		scrabled = ts_route_is_av_scrambled(g_dmx_dev, playing_pnode.video_pid, playing_pnode.audio_pid[playing_pnode.cur_audio]);
#endif
	}
	
    return scrabled;
}

